package pe.com.cotelasa.scp.dao.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Subqueries;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import pe.com.cotelasa.common.dao.DaoImpl;
import pe.com.cotelasa.common.dao.excepcion.DAOException;
import pe.com.cotelasa.scp.dao.IDAOOrdenPedido;
import pe.com.cotelasa.scp.dominio.common.ESTADO_REGISTRO;
import pe.com.cotelasa.scp.dominio.common.util.UtilitarioFecha;
import pe.com.cotelasa.scp.entidad.DetallePedidoOp;
import pe.com.cotelasa.scp.entidad.OrdenPedido;

/**
 *
 * @author usuario
 */
@Repository("daoOrdenPedido")
@SuppressWarnings("unchecked")
public class DAOOrdenPedidoImpl extends DaoImpl<OrdenPedido, Integer> implements IDAOOrdenPedido, Serializable {

    @Autowired
    private SessionFactory sessionFactory;

    @Transactional
    public OrdenPedido obtenerOrdenPedidoPorCodigo(OrdenPedido ordenPedido) throws DAOException {
        OrdenPedido ordenPedidoBuscado = null;
        try {
            ordenPedidoBuscado = (OrdenPedido) sessionFactory.getCurrentSession().createCriteria(OrdenPedido.class)
                    .add(Restrictions.eq("codigoOrdenPedido", ordenPedido.getCodigoOrdenPedido()))
                    .add(Restrictions.eq("idEmpresa", ordenPedido.getIdEmpresa()))
                    .add(Restrictions.eq("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor())).uniqueResult();
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
        return ordenPedidoBuscado;
    }

    @Transactional
    @Override
    public Collection<OrdenPedido> obtenerOrdenesPedidoPorEstado(OrdenPedido ordenPedido) throws DAOException {
        Collection<OrdenPedido> listaOrdenesPedido = new ArrayList<OrdenPedido>();
        try {
            sessionFactory.getCurrentSession().flush();
            listaOrdenesPedido = sessionFactory.getCurrentSession().createCriteria(OrdenPedido.class)
                    .add(Restrictions.eq("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                    .add(Restrictions.eq("idEmpresa", ordenPedido.getIdEmpresa()))
                    .add(Restrictions.like("estadoPedido", "%" + ordenPedido.getEstadoPedido() + "%"))
                    .addOrder(Order.asc("codigoOrdenPedido")).list();

        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
        return listaOrdenesPedido;
    }

    @Override
    public int buscarCantidadOP(OrdenPedido ordenPedido) throws DAOException {
        sessionFactory.getCurrentSession().flush();
        Long a = (Long) sessionFactory.getCurrentSession().createCriteria(OrdenPedido.class)
                .add(Restrictions.eq("clienteMarca", ordenPedido.getClienteMarca()))
                .add(Restrictions.eq("idEmpresa", ordenPedido.getIdEmpresa()))
                .add(Restrictions.eq("estadoRegistro", String.valueOf(ESTADO_REGISTRO.ACTIVO.getValor())))
                .add(Restrictions.le("fechaInicioPedido", UtilitarioFecha.toEndOfYear(UtilitarioFecha.obtenerAnio(ordenPedido.getFechaInicioPedido()))))
                .add(Restrictions.ge("fechaInicioPedido", UtilitarioFecha.toStartOfYear(UtilitarioFecha.obtenerAnio(ordenPedido.getFechaInicioPedido()))))
                .setProjection(Projections.rowCount())
                .uniqueResult();

        return a.intValue();
        //.list().get(0);
    }

    @Override
    public Collection<OrdenPedido> listarOrdenPedidosPorFiltro(OrdenPedido ordenPedido, Date fechaInicio, Date fechaFin) throws DAOException {

        try {
            Collection<OrdenPedido> lista = null;



            Criteria query = sessionFactory.getCurrentSession().createCriteria(OrdenPedido.class)
                    .addOrder(Order.desc("id"))
                    .createAlias("clienteMarca", "cli")
                    .add(Restrictions.eq("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                    .add(Restrictions.like("codigoOrdenPedido", "%" + ordenPedido.getCodigoOrdenPedido().trim() + "%"))
                    .add(Restrictions.eq("idEmpresa", ordenPedido.getIdEmpresa()))
                    .add(Restrictions.like("estadoPedido", "%" + ordenPedido.getEstadoPedido() + "%"))
                    .add(Restrictions.like("tipoOp", ordenPedido.getTipoOp()))
                    .add(Restrictions.like("cli.razonSocial", "%" + ordenPedido.getClienteMarca().getRazonSocial().trim() + "%"));
            if (!ordenPedido.getColeccionNombre().equalsIgnoreCase("")) {
                DetachedCriteria subCriteria = DetachedCriteria.forClass(DetallePedidoOp.class)
                        .add(Restrictions.like("nombreProducto", "%" + ordenPedido.getColeccionNombre().trim() + "%"))
                        .setProjection(Projections.distinct(Projections.property("idOrdenPedido")));

                query = query.add(Subqueries.propertyIn("id", subCriteria));
            }

            if (fechaInicio == null && fechaFin == null) {
                System.out.println("entro a todos");
                lista = query.list();
            } else if (fechaInicio != null && fechaFin != null) {
                System.out.println("entro a los dos");
                lista = query.add(Restrictions.ge("fechaInicioPedido", fechaInicio)).add(Restrictions.le("fechaInicioPedido", fechaFin)).list();
            } else if (fechaInicio == null) {
                System.out.println("entro a menor");
                lista = query.add(Restrictions.le("fechaInicioPedido", fechaFin)).list();
            } else if (fechaFin == null) {
                System.out.println("entro a final");
                lista = query.add(Restrictions.ge("fechaInicioPedido", fechaInicio)).list();
            }

            return lista;
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
    }
}
